package com.bamboocloud.im.simpleConnector.simpleConnector.utils;


import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

/**
 * JDK 1.6 以上 AES 是一种可逆加密算法，对用户的敏感信息加密处理 对原始数据进行AES加密后，再进行Base64编码转化；
 */
public class AESOperator {
    /*
     * 加密用的Key 可以用26个字母和数字组成 此处使用AES-128-CBC加密模式，key需要为16位。
     */
    private static String sKey = "abcdef0123456789";
    private static String ivParameter = "9iuj87y2hbi5wxl1";

    private final static String CIPHER = "AES/CBC/PKCS5Padding";
    private final static String AES = "AES";
    private final static String CHARSET = "UTF-8";

    public AESOperator() {

    }

    public AESOperator(String key) {
        sKey = key;
    }

    // 加密
    public static String encrypt(String sSrc) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER);
            byte[] raw = sKey.getBytes();
            SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
            IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());// 使用CBC模式，需要一个向量iv，可增加加密算法的强度
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(sSrc.getBytes(CHARSET));

            return DatatypeConverter.printBase64Binary(encrypted);
        } catch (Exception e) {
            throw e;
        }
    }

    // 解密
    public static String decrypt(String sSrc) throws Exception {
        try {
            byte[] raw = sKey.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
            Cipher cipher = Cipher.getInstance(CIPHER);
            IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            // byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);//
            // 先用base64解密
            byte[] encrypted1 = DatatypeConverter.parseBase64Binary(sSrc);
            ;// 先用base64解密
            byte[] original = cipher.doFinal(encrypted1);
            return new String(original, CHARSET);
        } catch (Exception e) {
            throw e;
        }
    }
    // 加密
    public static String encrypt(String sSrc, String key) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER);
            byte[] raw = get16Key(key).getBytes();
            SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
            IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());// 使用CBC模式，需要一个向量iv，可增加加密算法的强度
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(sSrc.getBytes(CHARSET));

            return DatatypeConverter.printBase64Binary(encrypted);
        } catch (Exception e) {
            throw e;
        }
    }
    // 解密
    public static String decrypt(String sSrc, String key) throws Exception {
        try {
            byte[] raw = get16Key(key).getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
            Cipher cipher = Cipher.getInstance(CIPHER);
            IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            // 先用base64解密
            byte[] encrypted1 = DatatypeConverter.parseBase64Binary(sSrc);
            // 先用base64解密
            byte[] original = cipher.doFinal(encrypted1);
            return new String(original, CHARSET);
        } catch (Exception e) {
            throw e;
        }
    }

    public static void main(String[] args) throws Exception {
        //AESOperator aesOper = new AESOperator("zbcdef0123456789");
        // 需要加密的字串
        String cSrc = "卜中云";String key="abcd";
        System.out.println(cSrc + "  长度为" + cSrc.length());
        // 加密
        long lStart = System.currentTimeMillis();
        String enString = AESOperator.encrypt(cSrc);
        System.out.println("加密后的字串是：" + enString + "长度为" + enString.length());
        String enStringBykey = AESOperator.encrypt(cSrc, key);
        System.out.println("enStringBykey:"+enStringBykey);
        long lUseTime = System.currentTimeMillis() - lStart;
        System.out.println("加密耗时：" + lUseTime + "毫秒");
        // 解密
        lStart = System.currentTimeMillis();
        String DeString = AESOperator.decrypt(enString);
        System.out.println("解密后的字串是：" + DeString + "  长度为" + DeString.length());
        lUseTime = System.currentTimeMillis() - lStart;
        System.out.println("解密耗时：" + lUseTime + "毫秒");
        String DeStringBykey = AESOperator.decrypt(enStringBykey, key);
        System.out.println("DeStringBykey:"+DeStringBykey);
    }
    private static String get16Key(String key){
        return new String(key+"aaaaaaaaaaaaaaaa").substring(0, 16);
    }
}
